package com.common.base.utils

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.PackageManager.NameNotFoundException
import android.net.wifi.WifiManager
import android.os.Build
import android.telephony.TelephonyManager
import android.util.Log
import androidx.core.content.ContextCompat
import com.common.base.R
import com.common.base.app.extras.getContext
import com.common.base.app.extras.yes
import com.umeng.commonsdk.statistics.common.DeviceConfig
import okhttp3.internal.notifyAll
import java.io.FileReader
import java.io.InputStreamReader
import java.io.LineNumberReader
import java.io.Reader
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method
import java.net.NetworkInterface
import java.util.*


/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：10/2/2023
 *
 * 描述：
 *
 * 修订历史：
 *
 */
object DeviceInfoUtil {
    fun getUniqueString(num: Int): Set<String> {
        val set: MutableSet<String> = HashSet()
        var i = 0
        while (true && i < num) {
            val random = Math.random()
            val str = random.toString().substring(2, 11)
            if (set.add(str)) i++
        }
        return set
    }

    /**
     * 取得Mac后，执行的函数
     */
    interface MacAddressListener {
        fun setMacAddress(macAddress: String?)
    }

    private val HEX_DIGITS = byteArrayOf(
        '0'.code.toByte(),
        '1'.code.toByte(),
        '2'.code.toByte(),
        '3'.code.toByte(),
        '4'.code.toByte(),
        '5'.code.toByte(),
        '6'.code.toByte(),
        '7'.code.toByte(),
        '8'.code.toByte(),
        '9'.code.toByte(),
        'A'.code.toByte(),
        'B'.code.toByte(),
        'C'.code.toByte(),
        'D'.code.toByte(),
        'E'.code.toByte(),
        'F'
            .code.toByte()
    )
    private const val INVALID_MAC_ADDRESS = "02:00:00:00:00:00"
    private var macAddress // 保存得到的Mac地址
            : String? = null
    private var already // 辅助判断是否已经得到MAC使线程无需等待
            = false
    private val macAddressListener: MacAddressListener = object : MacAddressListener {
        override fun setMacAddress(str: String?) {
            // 线程继续
            synchronized(this) {
                // 同步
                macAddress = str
                already = true
                notifyAll()
            }
        }
    }

    /**
     * 获取当前手机系统版本号
     *
     * @return 系统版本号
     */
    val systemVersion: String
        get() = Build.VERSION.RELEASE

    /**
     * 获取手机型号
     *
     * @return 手机型号
     */
    val systemModel: String
        get() = Build.MODEL

    /**
     * 获取手机厂商
     *
     * @return 手机厂商
     */
    val deviceBrand: String
        get() = Build.BRAND
    val deviceID: String
        get() = Build.SERIAL
    val oSver: String
        get() {
            var oSVer = ""
            try {
                oSVer += Build.VERSION.BASE_OS + "_"
                oSVer += Build.VERSION.RELEASE
            } catch (e: Exception) {
                oSVer += "_" + e.message
            }
            return oSVer
        }

    private val macInArray: ByteArray?
        private get() {
            try {
                val enumeration = NetworkInterface.getNetworkInterfaces() ?: return null
                while (enumeration.hasMoreElements()) {
                    val netInterface = enumeration.nextElement()
                    if (netInterface.name == "wlan0") {
                        return netInterface.hardwareAddress
                    }
                }
            } catch (e: Exception) {
                Log.e("tag", e.message, e)
            }
            return null
        }
    val longMac: Long
        get() {
            val bytes = macInArray
            if (bytes == null || bytes.size != 6) {
                return 0L
            }
            var mac = 0L
            for (i in 0..5) {
                mac = mac or (bytes[i].toInt() and 0xFF).toLong()
                if (i != 5) {
                    mac = mac shl 8
                }
            }
            return mac
        }

    fun getMacAddress(): String {
        val mac = formatMac(macInArray)
        return if (mac.isEmpty() || mac == INVALID_MAC_ADDRESS) {
            ""
        } else mac
    }

    private fun formatMac(bytes: ByteArray?): String {
        if (bytes == null || bytes.size != 6) {
            return ""
        }
        val mac = ByteArray(17)
        var p = 0
        for (i in 0..5) {
            val b = bytes[i]
            mac[p] = HEX_DIGITS[b.toInt() and 0xF0 shr 4]
            mac[p + 1] = HEX_DIGITS[b.toInt() and 0xF]
            if (i != 5) {
                mac[p + 2] = ':'.code.toByte()
                p += 3
            }
        }
        return String(mac)
    }

    /**
     * 需要的长度
     *
     * @param length
     */
    fun getRadom(length: Int): String {

        //获取一个随机数
        val rand = Math.random()
        //将随机数转换为字符串
        val str = rand.toString().replace("0.", "")
        var newStr = ""
        if (str.isNotEmpty() && str.length > length) {

            //截取字符串
            newStr = str.substring(0, length)
        }
        return newStr
    }

    /**
     * 截取字符串最后四位
     *
     * @param neumber
     * @return
     */
    fun cipherState(ctx: Context, neumber: String): String {
        var neumber = neumber
        var str = neumber

        // 防止空指针
        str.isEmpty().yes {
            return ""
        }
        neumber = neumber.substring(str.length - 4, str.length)
        str = ctx.getResources().getString(R.string.str_number_cipher, neumber)
        return str
    }

    fun getRandomString(length: Int): String { //length表示生成字符串的长度
        val base = "abcdefghijklmnopqrstuvwxyz0123456789"
        val random = Random()
        val sb = StringBuffer()
        for (i in 0 until length) {
            val number = random.nextInt(base.length)
            sb.append(base[number])
        }
        return sb.toString()
    }

    /**
     * 获取软件版本号
     *
     * @param context
     * @return
     */
    fun getVersionCode(context: Context): Int {
        var versionCode = 0
        try {
            // 获取软件版本号，对应AndroidManifest.xml下android:versionCode
            versionCode = context.getPackageManager().getPackageInfo(
                "com.smile.purcotton", 0
            ).versionCode
        } catch (e: NameNotFoundException) {
            e.printStackTrace()
        }
        return versionCode
    }

    /**
     * 获取软件版本号名字
     *
     * @param context
     * @return
     */
    fun getVersionName(context: Context): String? {
        try {
            val pkName: String = context.getPackageName()

//            int versionCode = context.getPackageManager()
//                    .getPackageInfo(pkName, 0).versionCode;
            return context.getPackageManager().getPackageInfo(
                pkName, 0
            ).versionName
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    /**
     * mac地址,获取网卡地址
     *
     * @param ctx
     * @return
     */
    @SuppressLint("MissingPermission")
    fun getMacAddress(cx: Context): String {
        var mac = ""
        try {
            val wifi = cx.getSystemService(Context.WIFI_SERVICE) as WifiManager
            val info = wifi.connectionInfo
            mac = info.macAddress
        } catch (e: java.lang.Exception) {
//            e.printStackTrace();
        }
        return mac ?: ""
    }

    /**
     * 获取手机的MAC地址
     *
     * @return
     */
    val mac: String?
        get() {
            var str = ""
            var macSerial = ""
            try {
                val pp = Runtime.getRuntime().exec(
                    "cat /sys/class/net/wlan0/address "
                )
                val ir = InputStreamReader(pp.inputStream)
                val input = LineNumberReader(ir)
                while (null != str) {
                    str = input.readLine()
                    if (str != null) {
                        macSerial = str.trim { it <= ' ' } // 去空格
                        break
                    }
                }
            } catch (ex: Exception) {
                ex.printStackTrace()
            }
            if (macSerial.isEmpty() || "" == macSerial) {
                try {
                    return loadFileAsString("/sys/class/net/eth0/address")
                        .uppercase(Locale.getDefault()).substring(0, 17)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
            return macSerial
        }

    @Throws(Exception::class)
    fun loadFileAsString(fileName: String?): String {
        val reader = FileReader(fileName)
        val text = loadReaderAsString(reader)
        reader.close()
        return text
    }

    @Throws(Exception::class)
    fun loadReaderAsString(reader: Reader): String {
        val builder = StringBuilder()
        val buffer = CharArray(4096)
        var readLength: Int = reader.read(buffer)
        while (readLength >= 0) {
            builder.append(buffer, 0, readLength)
            readLength = reader.read(buffer)
        }
        return builder.toString()
    }

    /**
     * 获取版本号
     *
     * @param ctx
     * @return
     */
    fun getVersion(ctx: Context): String {
        var version = "Unknow"
        try {
            val manager: PackageManager = ctx.getPackageManager()
            val info: PackageInfo = manager.getPackageInfo(ctx.getPackageName(), 0)
            version = info.versionName?:""
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return version
    }


    fun getRefIMEI(mContext: Context): String {
        var imei = ""
        try {
//            TelephonyManager tm = (TelephonyManager) mContext.getSystemService(TELEPHONY_SERVICE);
//
//            Method method = tm.getClass().getMethod("getImei");
//            imei = (String) method.invoke(tm);

            //实例化TelephonyManager对象
            val telephonyManager =
                mContext.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
            val method: Method = telephonyManager.javaClass.getMethod(
                "getDeviceId",
                Int::class.javaPrimitiveType
            )
            //获取IMEI号
            @SuppressLint("MissingPermission") val imei1 = telephonyManager.deviceId
            val imei2 = method.invoke(telephonyManager, 1) as String
            //获取MEID号
            val meid = method.invoke(telephonyManager, 2) as String
            imei = "imei1=" + imei1 + "imei2=" + imei2 + "meid=" + meid
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return imei
    }

    //使用硬件信息拼凑出来的15位号码
// 随便一个初始化//API>=9 使用serial号
    //13 位
    //        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
    @get:SuppressLint("MissingPermission")
    val uUID: String
        get() {
            var serial: String
            val m_szDevIDShort =
                "35" + Build.BOARD.length % 10 + Build.BRAND.length % 10 + (if (null != Build.CPU_ABI) Build.CPU_ABI.length else 0) % 10 + Build.DEVICE.length % 10 + Build.DISPLAY.length % 10 + Build.HOST.length % 10 + Build.ID.length % 10 + Build.MANUFACTURER.length % 10 + Build.MODEL.length % 10 + Build.PRODUCT.length % 10 + Build.TAGS.length % 10 + Build.TYPE.length % 10 + Build.USER.length % 10 //13 位

            //        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
            if (Build.VERSION.SDK_INT <= 28) {
                try {
                    serial = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        Build.getSerial()
                    } else {
                        Build.SERIAL
                    }
                    //API>=9 使用serial号
                    return UUID(
                        m_szDevIDShort.hashCode().toLong(),
                        serial.hashCode().toLong()
                    ).toString()
                } catch (exception: Exception) {
                    serial = "serial" + UUID.randomUUID().toString() // 随便一个初始化
                }
            } else {
                serial = Build.UNKNOWN + UUID.randomUUID().toString() // 随便一个初始化
            }

            //使用硬件信息拼凑出来的15位号码
            return UUID(
                m_szDevIDShort.hashCode().toLong(),
                serial.hashCode().toLong()
            ).toString()
        }

    fun getDeviceInfoOnUM(context: Context?): Array<String?> {
        val deviceInfo = arrayOfNulls<String>(2)
        try {
            if (context != null) {
                deviceInfo[0] = DeviceConfig.getDeviceIdForGeneral(context)
                deviceInfo[1] = DeviceConfig.getMac(context)
            }
        } catch (e: Exception) {
        }
        return deviceInfo
    }

    //判断是否安装了应用
    fun isAppAvilible(context: Context, pkName: String): Boolean {
        pkName.isEmpty().yes {
            return false
        }
        val packageManager: PackageManager = context.packageManager // 获取packagemanager
        val pinfo = packageManager.getInstalledPackages(0) // 获取所有已安装程序的包信息
        pinfo.toString()
        for (i in pinfo.indices) {
            val pn = pinfo[i].packageName
            if (pn.equals(pkName)) {
                return true
            }
        }
        return false
    }


    /**
     * @param context
     * @param packageName
     * @return
     * @Title isPackageExist
     * @Description .判断package是否存在
     * @date 2013年12月31日 上午9:49:59
     */
    fun isPackageExist(context: Context, packageName: String?): Boolean {
        val manager = context.packageManager
        val intent = Intent().setPackage(packageName)
        @SuppressLint("WrongConstant") val infos =
            manager.queryIntentActivities(intent, PackageManager.GET_INTENT_FILTERS)
        return infos.size >= 1
    }

    /**
     * 检测 响应某个Intent的Activity 是否存在
     * @param context
     * @param intent
     * @return
     */
    @SuppressLint("WrongConstant")
    open fun isIntentAvailable(context: Context, intent: Intent?): Boolean {
        val packageManager = context.packageManager
        val list = packageManager.queryIntentActivities(
            intent!!,
            PackageManager.GET_ACTIVITIES
        )
        return list.size > 0
    }

    /**
     * 获取软件包名
     *
     * @param ctx
     * @return
     */
    fun getPkgName(ctx: Context): String? {
        var pkgName = "Unknow"
        try {
            val manager = ctx.packageManager
            val info = manager.getPackageInfo(ctx.packageName, 0)
            pkgName = info.packageName
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return pkgName
    }



    /**
     * screen width
     */
    fun getScreenRatio(): String {
        val displayMetrics = getContext().resources.displayMetrics
        val width = displayMetrics.widthPixels
        val height = displayMetrics.heightPixels
        val aspectRatio = width.toFloat() / height.toFloat()

        val formattedAspectRatio = String.format(
            Locale.getDefault(),
            "%d:%d",
            (aspectRatio * 10).toInt(),
            10
        ) //将X:Y转化成X0:10的形式

        Log.d("TAG-getScreenRatio:", "---Aspect ratio $formattedAspectRatio")
        return formattedAspectRatio
    }


    /**
     * 获取SIM卡运营商
     *
     * @param context
     * @return
     */
    @SuppressLint("MissingPermission", "HardwareIds")
    fun getOperatorType(context: Context): String {
        var operator = ""
        try {
            val IMSI = (context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager).subscriberId
            if (IMSI == null || "" == IMSI) {
                return operator
            }
            if (IMSI.startsWith("46000") || IMSI.startsWith("46002")) {
                operator = "中国移动"
            } else if (IMSI.startsWith("46001")) {
                operator = "中国联通"
            } else if (IMSI.startsWith("46003")) {
                operator = "中国电信"
            }
            return operator
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        return operator
    }


    fun getCarrier(context: Context): String {
        try {
            val permissionStatus = ContextCompat.checkSelfPermission(context, "android.permission.READ_PRIVILEGED_PHONE_STATE")
            if (Build.VERSION.SDK_INT >= 29 && permissionStatus == PackageManager.PERMISSION_GRANTED) {
                val tm =
                    context.applicationContext.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
                if (tm != null) {
                    return if(tm.simCarrierIdName == null) "" else tm.simCarrierIdName.toString() //getImei(0);
                }
            }
            return ""
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        return ""
    }


    fun getOaid(context: Context?): String {
        try {
            val identifierClass = Class.forName("com.android.id.IdentifierManager")
            val oaidMerhod = identifierClass.getMethod("getOAID", Context::class.java)
            val res = oaidMerhod.invoke(null, context)
            return res?.toString() ?: ""
        } catch (e: NoSuchMethodException) {
            e.printStackTrace()
        } catch (e: InvocationTargetException) {
            e.printStackTrace()
        } catch (e: IllegalAccessException) {
            e.printStackTrace()
        } catch (e: ClassNotFoundException) {
            e.printStackTrace()
        }
        return ""
    }

    private fun isValidMacAddress(mac: String): Boolean {
        // 正则表达式匹配标准 MAC 地址格式
        val macRegex = Regex("^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}\$")
        return macRegex.matches(mac)
    }

    private fun formatMacAddress(mac: String): String {
        // 去除非法字符（非十六进制字符）
        val cleanedMac = mac.replace(Regex("[^0-9A-Fa-f]"), "")
        // 每 2 个字符插入冒号
        return cleanedMac.chunked(2).joinToString(":")
    }

    fun checkAndFormatMacAddress(mac: String): String {
        return if (isValidMacAddress(mac)) {
            mac // 如果格式正确，直接返回
        } else {
            formatMacAddress(mac) // 如果格式不正确，格式化后返回
        }
    }
}